LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;

ENTITY DataLoad IS
	PORT(
		Clk : IN std_logic;
		Start : IN std_logic;
		Finish : OUT std_logic;
		Reset : IN std_logic;
		SUp, SDown, SLeft, SRight, SCenter : OUT std_logic_vector(15 downto 0);
		PosX, PosY : IN std_logic_vector(4 downto 0);

		PrimReadAddr    : OUT std_logic_vector(9 downto 0);
		PrimReadData    : IN  std_logic_vector(15 downto 0)
	);
END DataLoad;

ARCHITECTURE rtl OF DataLoad IS
	TYPE State_Type IS (idle, Rup, Rdown, Rleft, Rright, Rcenter, ready);
	--TYPE Read_Type IS (InAddr, Reading, Result);
	SIGNAL state : State_Type;
	SIGNAL readstate : std_logic_vector(1 downto 0);
BEGIN
	PROCESS(Clk, Reset)
	BEGIN
		IF Reset = '0' THEN
			state <= idle;
			Finish <= '0';
		ELSIF rising_edge(Clk) THEN
			CASE state IS
				WHEN idle =>
					IF Start = '1' THEN	-- if start signal enables it;
						state <= Rup;
						readstate <= "00";
					ELSE
						state <= idle;
					END IF;
					Finish <= '0';
				WHEN Rup =>
					CASE readstate IS
						WHEN "11" =>
							readstate <= "00";
							state <= Rdown;
							
							SUp <= PrimReadData;	-- out data
						WHEN "00" =>
							readstate <= "01";
							
							PrimReadAddr <= (PosY -1) & PosX;	-- input address
						WHEN OTHERS =>
							readstate <= readstate +1;
					END CASE;
				WHEN Rdown =>
					CASE readstate IS
						WHEN "11" =>
							readstate <= "00";
							state <= Rleft;
							
							SDown <= PrimReadData;	-- out data
						WHEN "00" =>
							readstate <= "01";
							
							PrimReadAddr <= (PosY +1) & PosX;	-- input address
						WHEN OTHERS =>
							readstate <= readstate +1;
					END CASE;
				WHEN Rleft =>
					CASE readstate IS
						WHEN "11" =>
							readstate <= "00";
							state <= Rright;
							
							SLeft <= PrimReadData;	-- out data
						WHEN "00" =>
							readstate <= "01";
							
							PrimReadAddr <= PosY & (PosX -1);	-- input address
						WHEN OTHERS =>
							readstate <= readstate +1;
					END CASE;
				WHEN Rright =>
					CASE readstate IS
						WHEN "11" =>
							readstate <= "00";
							state <= Rcenter;
							
							SRight <= PrimReadData;	-- out data
						WHEN "00" =>
							readstate <= "01";
							
							PrimReadAddr <= PosY & (PosX +1);	-- input address
						WHEN OTHERS =>
							readstate <= readstate +1;
					END CASE;
				WHEN Rcenter =>
					CASE readstate IS
						WHEN "11" =>
							readstate <= "00";
							state <= ready;
							Finish <= '1';
							
							SCenter <= PrimReadData;	-- out data
						WHEN "00" =>
							readstate <= "01";
							
							PrimReadAddr <= PosY & PosX;	-- input address
						WHEN OTHERS =>
							readstate <= readstate +1;
					END CASE;
				WHEN ready =>
					state <= idle;
				WHEN OTHERS =>
			END CASE;															
		END IF;
	END PROCESS;
END rtl;
